1 module hip.graphics.g2d.profiling; 2 3 /** 4 * Draw GC stats on screen for instant feedback. 5 * Params: 6 * x = X position 7 * y = Y Position. If it is < 0, it will draw at the default Y which is in the lower part of the screen 8 */ 9 void drawGCStats(int x = 0, int y = -1) 10 { 11 import hip.config.opts; 12 import hip.util.string; 13 import hip.util.data_structures; 14 import hip.math.utils; 15 import hip.graphics.g2d.renderer2d; 16 if(x < 0) 17 x = 0; 18 if(y < 0) 19 { 20 import hip.hiprenderer.renderer; 21 y = HipRenderer.getCurrentViewport.worldHeight; 22 } 23 24 static struct ByteUnit 25 { 26 double data; 27 string unit; 28 29 SmallString asSmallString() @nogc 30 { 31 return SmallString( 32 SmallString(data).toString.limitDecimalPlaces(2), 33 unit 34 ); 35 } 36 } 37 38 ByteUnit formatFromBytes(size_t byteCount) @nogc 39 { 40 double actualResult = byteCount; 41 42 if(actualResult <= 1000) 43 return ByteUnit(floorDecimal(actualResult, 2), " B"); 44 actualResult/= 1000; 45 if(actualResult <= 1000) 46 return ByteUnit(floorDecimal(actualResult, 2), " KB"); 47 actualResult/= 1000; 48 return ByteUnit(floorDecimal(actualResult, 2), " MB"); 49 actualResult/= 1000; 50 return ByteUnit(floorDecimal(actualResult, 2), " GB"); 51 } 52 53 static if(CustomRuntime) 54 { 55 import core.arsd.memory_allocation; 56 SmallString str = SmallString("Memory Allocated ", formatFromBytes(getMemoryAllocated()).asSmallString().toString); 57 drawText(str.toString, x, y, 1.0, HipColor(0,50,0), HipTextAlign.botLeft); 58 59 } 60 else 61 { 62 import core.memory; 63 GC.Stats stats = GC.stats; 64 GC.ProfileStats prof = GC.profileStats; 65 SmallString timeOnPause = SmallString.get(); 66 SmallString timeOnCollection = SmallString.get(); 67 68 prof.totalPauseTime.toString((string data) 69 { 70 timeOnPause~= data; 71 }); 72 prof.totalCollectionTime.toString((string data) 73 { 74 timeOnCollection~= data; 75 }); 76 77 78 scope BigString str = BigString( 79 "Memory Used: ", formatFromBytes(stats.usedSize).asSmallString.toString, 80 "\nFree Memory: ", formatFromBytes(stats.freeSize).asSmallString.toString, 81 "\nPaused Time: ", timeOnPause.toString, 82 "\nCollection Time:", timeOnCollection.toString, 83 "\nCollections Count: ", prof.numCollections, 84 ); 85 drawText(str.toString, x, y, 1.0, HipColor(0, 0, 0, 150), HipTextAlign.botLeft); 86 } 87 } 88 89 90 private __gshared float lastTiming; 91 private __gshared float lastTime; 92 private __gshared int count; 93 private __gshared immutable countReset = 30; 94 95 void setFrameInitTime() 96 { 97 import hip.util.time; 98 if(++count == countReset) 99 { 100 lastTime = HipTime.getCurrentTimeAsMs(); 101 count = 0; 102 } 103 } 104 void drawTimings(int x = -1, int y = 0, bool clearTiming = false) 105 { 106 import hip.util.time; 107 import hip.util.string; 108 import hip.graphics.g2d.renderer2d; 109 110 if(count == 0) 111 lastTiming = HipTime.getCurrentTimeAsMs() - lastTime; 112 SmallString timeProcessing = SmallString("CPU Time: ", SmallString(lastTiming).toString.limitDecimalPlaces(3), "ms"); 113 114 if(x == -1) 115 x = getCurrentViewport().worldWidth; 116 117 drawText(timeProcessing.toString, x, 0, 1.0f, HipColor.white, HipTextAlign.topRight); 118 119 // if(clearTiming) 120 // lastTime = currTime; 121 }